#ifndef _COMM_H
#define _COMM_H
#define _XOPEN_SOURCE // 使用#include <sys/ipc.h> 头文件时定义，不然会有警告
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>

#define PATHNAME "."
#define PROJ_ID 0X66
// 共享内存的大小，一般建议是4KB的整数倍
// 系统分配共享内存是以4KB为单位的！ ----- 内存划分内存块的基本单位page
#define MAX_SIZE 4096

// 获取key值
key_t getkey()
{
    // 创建shmget函数需要使用的key值
    key_t k = ftok(PATHNAME, PROJ_ID);
    // if (k < 0)
    // {
    //     fprintf(stderr, errno);
    //     exit(1);
    // }
    return k;
}

// 实现创建共享内存
int getShmHelper(key_t k, int flags)
{
    int shmid = shmget(k, MAX_SIZE, flags);
    if (shmid < 0)
    {
        printf("%s\n", errno);
        exit(2);
    }
    return shmid;
}

// 创建
int createShm(key_t k)
{
    return getShmHelper(k, IPC_CREAT | IPC_EXCL | 0666);
}

// 获取共享内存标识符
int getShm(key_t k)
{
    return getShmHelper(k, IPC_CREAT /*0*/);
}

// 把创建的共享内存映射到需要使用的进程中
void *attchShm(int shmid)
{
    void *mem = shmat(shmid, NULL, 0);
    if ((long)mem == -1)
    {
        perror("映射错误：");
        exit(3);
    }
    return mem;
}

// 把当前进程地址空间当中的共享内存进行卸载
void datechShm(void *start)
{
    if (shmdt(start) == -1)
    {
        printf("卸载失败");
    }
}

// 删除共享内存
void delShm(int shmid)
{
    if (shmctl(shmid, IPC_RMID, NULL) == -1)
    {
        printf("删除共享内存失败");
    }
}

#endif